package com.danbay.framework.kafka.coap;

import com.danbay.framework.exception.MessageCodeException;
import com.danbay.framework.protocol.command.codec.JsonDataDecoder;
import com.danbay.framework.utils.JsonUtils;
import com.danbay.framework.utils.ReflectUtils;
import com.danbay.framework.utils.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;

import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author SJG
 *         2017/11/20.
 */
@Slf4j
public class CoAPJsonDataDecoder extends JsonDataDecoder {
    ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public <T> T decode(String data, Type dest) throws MessageCodeException {
        //无数据不解析json
        if (StringUtils.isBlank(data)) {
            return null;
        }
        log.info("start decode CoAP json:{}", data);
        try {
            CoAPMessage coAPMessage;
            try {
                coAPMessage = objectMapper.readValue(data, CoAPMessage.class);
            } catch (IOException e) {
                log.error("parse coAP message error", e);
                return null;
            }

            //原始类型,直接返回解析结果
            if (dest.getTypeName().indexOf(".") == -1 || dest.getTypeName().indexOf("java.lang.") == 0) {
                return (T) coAPMessage.getPayload();
            }
            //其它类型
            T obj;
            String payload = coAPMessage.getPayload();
            if (!StringUtils.isBlank(payload)) {
                obj = JsonUtils.parse(objectMapper, coAPMessage.getPayload(), dest);
            }else{
                //如果payload中无json数据,则创建空的对象
                if(dest instanceof ParameterizedTypeImpl){
                    obj= (T) ((ParameterizedTypeImpl)dest).getRawType().newInstance();
                }else{
                    obj= (T) ((Class)dest).newInstance();
                }
            }

            //从uriQuery中获取其它属性，附加到payload中
            List<String> uriQueries = coAPMessage.getUriQuery();
            Map<String, Object> propertiesMap = new HashMap<>(uriQueries.size());
            for (String str : uriQueries) {
                //将a=b的字符串转为key-value
                String[] arr = str.split("=");
                propertiesMap.put(arr[0], arr[1]);
            }
            //合并uriQuery中的参数
            if (propertiesMap.size() > 0) {
                return ReflectUtils.applyProperties(obj, propertiesMap);
            }
            return obj;
        } catch (Exception e) {
            throw new MessageCodeException("json解析失败,错误码:1002", 1002, e);
        }
    }
}
